﻿using System;
using System.Collections.ObjectModel;
using System.Windows;
using FU.Capstones.IMS.Web.Common;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.DataContracts;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.EventArgs;
using FU.Capstones.IMS.Web.Silverlight.Models;
using FU.Capstones.IMS.Web.Silverlight.Popups;
using Microsoft.Practices.Prism.Commands;
using Navigation.Silverlight;

namespace FU.Capstones.IMS.Web.Silverlight.ViewModels
{
    public class PartnerDetailViewModel : ViewModelBase
    {
        public PartnerDetailViewModel()
        {
            Model = new PartnerDetailModel();
            ((PartnerDetailModel)Model).GetSinglePartnerCompleted += DoGetSinglePartnerCompleted;
            ((PartnerDetailModel)Model).InsertPartnerCompleted += DoInsertPartnerCompleted;
            ((PartnerDetailModel)Model).UpdatePartnerCompleted += DoUpdatePartnerCompleted;
            ((PartnerDetailModel)Model).DeleteContactCompleted += DoDeleteContactCompleted;

            ErrorMessageVisibility = Visibility.Collapsed;
            MessageVisibility = Visibility.Collapsed;

            CanEditOrAdd = CurrentUser.CanEditPartner || CurrentUser.CanAddPartner;
            CanAdd = CurrentUser.CanAddPartner;
        }

        #region Do Completed Methods

        void DoUpdatePartnerCompleted(object sender, FeedbackCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);

                if (e.Result.IsSuccessful)
                {
                    Backup();
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoInsertPartnerCompleted(object sender, SingleFeedbackCompletedEventArgs<int> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    IsCreateNew = false;
                    Partner.PartnerID = e.Result.Data;
                    Backup();
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetSinglePartnerCompleted(object sender, SingleFeedbackCompletedEventArgs<Partner> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    Partner = new Partner()
                    {
                        Address = e.Result.Data.Address,
                        PartnerCode = e.Result.Data.PartnerCode,
                        Description = e.Result.Data.Description,
                        Email = e.Result.Data.Email,
                        PartnerID = e.Result.Data.PartnerID,
                        CompanyName = e.Result.Data.CompanyName,
                        ContactCollection = e.Result.Data.ContactCollection,
                        Fax = e.Result.Data.Fax,
                        IsSupplier = e.Result.Data.IsSupplier,
                        MobilePhone = e.Result.Data.MobilePhone,
                        OfficePhone = e.Result.Data.OfficePhone,
                        Rating = e.Result.Data.Rating
                    };
                    Backup();
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoDeleteContactCompleted(object sender, FeedbackCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                MessageVisibility = Visibility.Visible;
            }
            else
            {
                Message = e.Result.Message;
                if (e.Result.IsSuccessful)
                {
                   ServiceCallCounter += ((PartnerDetailModel)Model).GetSinglePartnerAsync(partner.PartnerID);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        #endregion

        #region Commands

        #region SaveCommand

        private DelegateCommand<object> saveCommand;
        public DelegateCommand<object> SaveCommand
        {
            get
            {
                if (saveCommand == null)
                    saveCommand = new DelegateCommand<object>(DoSaveCommand);
                return saveCommand;
            }
        }

        private void DoSaveCommand(object obj)
        {
            Partner.ValidateAll();
            if (!Partner.HasErrors)
            {
                if (isCreateNew)
                {
                    ServiceCallCounter += ((PartnerDetailModel)Model).InsertPartnerAsync(Partner);
                }
                else
                {
                    ServiceCallCounter += ((PartnerDetailModel)Model).UpdatePartnerAsync(Partner);
                }
            }
            else
            {
                Message = WebConstants.InvalidInputDataMessage;
                SetMessageVisibility(false);
            }
        }

        #endregion

        #region CancelCommand

        private DelegateCommand<object> cancelCommand;
        public DelegateCommand<object> CancelCommand
        {
            get
            {
                if (cancelCommand == null)
                    cancelCommand = new DelegateCommand<object>(DoCancelCommand);
                return cancelCommand;
            }
        }

        private void DoCancelCommand(object obj)
        {
            NavigationManager.NavigateTo(WebConstants.NavigationPages.PartnerList);
        }

        #endregion

        #region ResetCommand

        private DelegateCommand<object> resetCommand;
        public DelegateCommand<object> ResetCommand
        {
            get
            {
                if (resetCommand == null)
                    resetCommand = new DelegateCommand<object>(DoResetCommand);
                return resetCommand;
            }
        }

        private void DoResetCommand(object obj)
        {
            if (isCreateNew)
                Partner = new Partner();
            else
            {
                Partner = partnerTemp;
                Backup();
            }
        }

        #endregion

        #region DeleteContactCommand

        private DelegateCommand<int?> deleteContactCommand;
        public DelegateCommand<int?> DeleteContactCommand
        {
            get
            {
                if (deleteContactCommand == null)
                {
                    deleteContactCommand = new DelegateCommand<int?>(DoDeleteContactCommand);
                }
                return deleteContactCommand;
            }
        }

        private void DoDeleteContactCommand(int? obj)
        {
            if (obj.HasValue)
            {
                DeleteConfirmationPopup popup = new DeleteConfirmationPopup();
                popup.Show();
                popup.Closed += (sender, e) =>
                {
                    if (popup.DialogResult.HasValue && popup.DialogResult.Value)
                    {
                        ServiceCallCounter +=
                            ((PartnerDetailModel)Model).DeleteContactAsync(obj.Value);
                        currentContactID = obj.Value;
                        Message = "Deleting the selected Contact!";
                    }
                };
            }
        }

        #endregion

        #region CreateCommand

        private DelegateCommand<Contact> createCommand;
        public DelegateCommand<Contact> CreateCommand
        {
            get
            {
                if (createCommand == null)
                {
                    createCommand = new DelegateCommand<Contact>(DoCreateCommand);
                }
                return createCommand;
            }
        }

        private void DoCreateCommand(object obj)
        {
            AddNewContactPopup popup = new AddNewContactPopup(Partner.PartnerID);
            popup.Show();
            popup.Closed += (sender, e) =>
                                {
                                    if (popup.DialogResult.HasValue && popup.DialogResult.Value)
                                        ServiceCallCounter +=
                                            ((PartnerDetailModel) Model).GetSinglePartnerAsync(partner.PartnerID);

                                };
        }

        #endregion


        #endregion

        #region Binding Properties

        private Partner partner;
        public Partner Partner
        {
            get { return partner; }
            set
            {
                if (!ReferenceEquals(partner, value))
                {
                    partner = value;
                    RaisePropertyChanged(() => Partner);
                }
            }
        }

        private ObservableCollection<Role> roleCollection;
        public ObservableCollection<Role> RoleCollection
        {
            get { return roleCollection; }
            set
            {
                if (!ReferenceEquals(roleCollection, value))
                {
                    roleCollection = value;
                    RaisePropertyChanged(() => RoleCollection);
                }
            }
        }

        private ObservableCollection<EmploymentType> eTypeCollection;
        public ObservableCollection<EmploymentType> EmploymentTypeCollection
        {
            get { return eTypeCollection; }
            set
            {
                if (!ReferenceEquals(eTypeCollection, value))
                {
                    eTypeCollection = value;
                    RaisePropertyChanged(() => EmploymentTypeCollection);
                }
            }
        }

        private bool isCreateNew;
        public bool IsCreateNew
        {
            get { return isCreateNew; }
            set
            {
                if (!ReferenceEquals(isCreateNew, value))
                {
                    isCreateNew = value;
                    RaisePropertyChanged(() => IsCreateNew);
                }
            }
        }

        #endregion

        #region Fields

        private Partner partnerTemp;
        private int currentContactID;

        #endregion

        #region Implementation of INavigationAware

        public override void OnNavigate(object extraData)
        {
            int? partnerID = (int?)extraData;
            IsCreateNew = (partnerID.HasValue == false || partnerID.Value == 0);
            if (!isCreateNew)
            {
                ServiceCallCounter += ((PartnerDetailModel)Model).GetSinglePartnerAsync(partnerID.Value);
            }
            else
            {
                Partner = new Partner();
            }
            Message = "Loading data from server!";
        }

        public override void OnLeave()
        {
            //throw new NotImplementedException();
        }

        #endregion
        
        private void Backup()
        {
            if (Partner != null)
            {
                partnerTemp = new Partner()
                {
                    Address = partner.Address,
                    Description = partner.Description,
                    Email = partner.Email,
                    PartnerID = partner.PartnerID,
                    PartnerCode = partner.PartnerCode,
                    CompanyName = partner.CompanyName,
                    ContactCollection = partner.ContactCollection,
                    Fax = partner.Fax,
                    IsSupplier = partner.IsSupplier,
                    MobilePhone = partner.MobilePhone,
                    OfficePhone = partner.OfficePhone,
                    Rating = partner.Rating
                };
            }
        }
    }
}
